package com.ziytek.web.citizen.service;

import com.google.gson.Gson;
import com.ziytek.web.citizen.config.caffeine.CaffeineUtil;
import com.ziytek.web.citizen.constant.NumConstant;
import com.ziytek.web.citizen.constant.ServerConstant;
import com.ziytek.web.citizen.mapper.OperationDetailMapper;
import com.ziytek.web.citizen.model.bean.CommandIssuedSuccess;
import com.ziytek.web.citizen.model.bean.JobTimes;
import com.ziytek.web.citizen.util.KeyUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author fenghx
 */

@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class JobTimesFinishService {
    private final Gson gson;
    private final OperationDetailMapper operationDetailMapper;

    public Pair<Boolean, Integer> jobTimesFinish(CommandIssuedSuccess cs) {
        if (null == cs) {
            return Pair.of(true, NumConstant.INT_ZERO);
        }

        log.info("JobTimesFinishService判断推送是否完成 {}", gson.toJson(cs));
        return cs.isSingleChannel() ?
                singe(cs, ServerConstant.SINGLE_TYPE_SINGLE) :
                all(cs.getReqCabinetNo(), cs.getOrder(), cs.getInterruptOrEndStepId());
    }

    private Pair<Boolean, Integer> singe(CommandIssuedSuccess cs, int singleType) {
        var jobTimes = new JobTimes();
        jobTimes.setOrderNo(cs.getOrder());
        jobTimes.setBoardNo(cs.getBoardNo());
        jobTimes.setChannelNo(cs.getChannelNo());
        jobTimes.setCabinetNo(Integer.parseInt(cs.getReqCabinetNo()));
        jobTimes.setInterruptOrEndStepId(cs.getInterruptOrEndStepId());
        jobTimes.setSingeType(singleType);

        var cacheKey = KeyUtil.jobTimesKey(jobTimes);
        JobTimes finishJobTimes = CaffeineUtil.get(cacheKey);

        //log.info("是否完成：key:{}-{} ", cacheKey, finishJobTimes == null);
        if (finishJobTimes == null) {
            return Pair.of(true, NumConstant.INT_ZERO);
        }

        log.info("finishJobTimes判断推送是否完成:{}", gson.toJson(finishJobTimes));
        return Pair.of(finishJobTimes.getTimeCount() <= finishJobTimes.getTimes(), finishJobTimes.getTimeCount() - finishJobTimes.getTimes());
    }

    private Pair<Boolean, Integer> all(String cabinetNoStr, int orderNo, long stepId) {
        var cabinetNo = String.valueOf(Integer.parseInt(String.valueOf(cabinetNoStr)));
        var operationDetailList = operationDetailMapper.findDetailNotSingleType(cabinetNo, ServerConstant.SINGLE_TYPE_ALL);
        if (CollectionUtils.isEmpty(operationDetailList)) {
            return Pair.of(true, NumConstant.INT_ZERO);
        }

        var count = NumConstant.INT_ZERO;
        for (var od : operationDetailList) {
            var cis = new CommandIssuedSuccess();
            cis.setOrder(orderNo);
            cis.setReqCabinetNo(cabinetNoStr);
            cis.setChannelNo(od.getCellNum());
            cis.setInterruptOrEndStepId(stepId);
            cis.setBoardNo(od.getBoardAddress());
            var pair = singe(cis, ServerConstant.SINGLE_TYPE_ALL);
            if (!pair.getLeft()) {
                count = Math.max(count, pair.getRight());
                break;
            }
        }

        log.info("[整体指令]是否完成cabinetNo:{}-orderNo:{}-stepId:{}-剩余count:{}", cabinetNoStr, orderNo, stepId, count);
        return Pair.of(NumConstant.INT_ZERO == count, count);
    }
}
